import redis
from typing import Optional, Union


class RedisClient:
    """Redis连接池及字符串操作封装"""

    def __init__(self, host: str = 'localhost', port: int = 6379,
                 db: int = 0, password: Optional[str] = None,
                 max_connections: int = 10):
        """
        初始化Redis连接池

        Args:
            host: Redis主机地址
            port: Redis端口
            db: 数据库编号
            password: 认证密码
            max_connections: 最大连接数
        """
        self.pool = redis.ConnectionPool(
            host=host,
            port=port,
            db=db,
            password=password,
            max_connections=max_connections,
            decode_responses=True  # 自动解码字节为字符串
        )
        self.client = redis.Redis(connection_pool=self.pool)

    def set(self, key: str, value: Union[str, int, float],
            ex: Optional[int] = None, px: Optional[int] = None,
            nx: bool = False, xx: bool = False) -> bool:
        """
        设置字符串值

        Args:
            key: 键
            value: 值
            ex: 过期时间(秒)
            px: 过期时间(毫秒)
            nx: 仅当键不存在时设置
            xx: 仅当键存在时设置

        Returns:
            操作是否成功
        """
        return self.client.set(key, value, ex=ex, px=px, nx=nx, xx=xx)

    def get(self, key: str) -> Optional[str]:
        """获取字符串值"""
        return self.client.get(key)

    def mset(self, mapping: dict) -> bool:
        """批量设置字符串值"""
        return self.client.mset(mapping)

    def mget(self, keys: list) -> list:
        """批量获取字符串值"""
        return self.client.mget(keys)

    def getset(self, key: str, value: str) -> Optional[str]:
        """设置新值并返回旧值"""
        return self.client.getset(key, value)

    def incr(self, key: str, amount: int = 1) -> int:
        """原子性递增"""
        return self.client.incr(key, amount)

    def decr(self, key: str, amount: int = 1) -> int:
        """原子性递减"""
        return self.client.decr(key, amount)

    def append(self, key: str, value: str) -> int:
        """追加字符串"""
        return self.client.append(key, value)

    def strlen(self, key: str) -> int:
        """获取字符串长度"""
        return self.client.strlen(key)

    def exists(self, key: str) -> bool:
        """检查键是否存在"""
        return self.client.exists(key) == 1

    def delete(self, key: str) -> bool:
        """删除键"""
        return self.client.delete(key) == 1

    def expire(self, key: str, seconds: int) -> bool:
        """设置过期时间"""
        return self.client.expire(key, seconds)

    def close(self) -> None:
        """关闭连接池"""
        self.client.close()

myRedis = RedisClient()